import { game, Game, gfx, Material, assetManager, EffectAsset } from "cc";

function loadBundlePromise(bundleName: string) {
    return new Promise((resolve, reject) => {
        assetManager.loadBundle(bundleName, (err, bundle) => err ? reject(err) : resolve(bundle));
    })
}

function loadAnyPromise(assetNames: string[]) {
    return new Promise((resolve, reject) => {
        assetManager.loadAny(assetNames, (err, assets) => err ? reject(err) : resolve(assets));
    })
}

class CinestationShareAssets {
    public viewMaterial!: Material;
    public lineMaterial!: Material;

    constructor() {
        this.lineMaterial = new Material();
        this.lineMaterial._uuid = "cinestation-line-material";
        this.viewMaterial = new Material();
        this.viewMaterial._uuid = "cinestation-view-material";
        game.on(Game.EVENT_GAME_INITED, this._onGameInited, this);
    }

    private _onGameInited() {
        this._loadAssets().then(() => this._compile());
    }

    private async _loadAssets() {
        if (!CC_EDITOR) {
            await loadBundlePromise("cinestation");
        }
        const assetMap = {
            '83789b2f-cb79-47f6-abfe-65f7d46aae71': 'cinestation/view',
        };
        let assets = await loadAnyPromise(Object.keys(assetMap)) as any[];
        let loadedAssets = assets instanceof Array ? assets : [assets];
        for (let v of loadedAssets) {
            v.addRef();
            v.name = assetMap[v._uuid];
            EffectAsset.register(v);
        }
    }

    private _compile() {
        this.lineMaterial.initialize({
            effectName: "builtin-unlit",
            defines: { USE_VERTEX_COLOR: true },
            states: { primitive: gfx.PrimitiveMode.LINE_LIST }
        });
        this.lineMaterial.passes.forEach(v => v.tryCompile());
        this.viewMaterial.initialize({
            effectName: "cinestation/view",
            technique: 1,
        });
        this.viewMaterial.passes.forEach(v => v.tryCompile());
    }

    public __setDebugProperty(k: string, v: any) {
        this.viewMaterial.setProperty(k, v);
    }
}

export const cinestationShareAssets = new CinestationShareAssets();

